package com.config
{
	import com.core.utils.StringUtil;
	import com.core.utils.geom.ArrayUtil;
	import com.data.ConfigData;
	import com.game.base.NonPerformer;
	import com.game.base.Performer;
	import com.game.base.SimulationObject;
	import com.game.baseobj.role.ClipDirection;
	import com.game.performers.Actor;
	import com.module.chat.ChatMessage;
	import com.module.itemeditor.CfgItem;
	import com.module.itemeditor.IntegerProperty;
	import com.module.itemeditor.StringProperty;
	import com.module.mail.MailContent;
	import com.module.mail.MailTitle;
	import com.server.User;
	
	import flash.display.DisplayObject;
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.net.SharedObject;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	import flash.system.ApplicationDomain;
	import flash.system.LoaderContext;
	import flash.utils.ByteArray;
	import flash.utils.Dictionary;
	import flash.utils.getQualifiedClassName;
	import flash.utils.setTimeout;

	[Event(name="complete",type="flash.events.Event")]
	
	public class GameConfig extends EventDispatcher
	{
		private static var _instance:GameConfig;

		public static var domain:ApplicationDomain;
		
		public function get company():String
		{
			return _company;
		}

		public function get date():String
		{
			return _date;
		}

		public function get version():String
		{
			return _version;
		}

		public static function get instance():GameConfig
		{
			if(!_instance)
				_instance = new GameConfig();
			return _instance;
		}
		
		private var _version:String;
		private var _date:String;
		private var _company:String;
		
		private var uiswfpath:String;
		private var _uiApplication:Object;
		public function get ui():Object
		{
			return _uiApplication;
		}
		
		private var sceneswfpath:String;
		private var _scene:LoaderInfo;
		public function get scene():DisplayObject
		{
			return _scene.content as DisplayObject;
		}
		
		private var actionconfigpath:String;
		private var actionconfig:Dictionary;
		public function get actionConfig():Dictionary
		{
			return actionconfig;
		}
		
		private var mapsconfig:Dictionary;
		
		public function getMapObj(id:int):Object
		{
			return mapsconfig[id];
		}
		
		
		public var mainserver:String;
		public var mainport:int = 8888;
		
		public var chatserver:String;
		public var chatport:int = 3500;
		
		[Bindable]
		public var issaveaccount:Boolean = false;
		
		[Bindable]
		private var _saveAccount:String = "";
		
		public function get saveAccount():String
		{
			return _saveAccount;
		}
		
		public function set saveAccount(value:String):void
		{
			var so:SharedObject = SharedObject.getLocal("rpgcookies");
			if(issaveaccount){
				so.data.saveaccount = value;
			}
			else
			{
				so.data.saveaccount = "";
			}
			so.flush();	
			_saveAccount = value;
		}

		public function GameConfig()
		{
			var so:SharedObject = SharedObject.getLocal("rpgcookies");
			if(so.data.saveaccount){
				issaveaccount = true;
				_saveAccount = so.data.saveaccount;
			}
			GameConfig.initAllCommClass();
		}
		
		public static function initAllCommClass():void
		{
			User;
			CfgItem;
			IntegerProperty;
			StringProperty;
			
			SimulationObject;
			Performer;
			NonPerformer;
			Actor;
			
			ChatMessage;
			
			//mail
			MailContent;
			MailTitle;
		}
		
		public function init():void
		{
			loadShellConfig();
		}
		
		private function loadShellConfig():void
		{
			var loader:URLLoader = new URLLoader();
			loader.addEventListener(Event.COMPLETE,loadShellConfigCompletedHandler);
			loader.addEventListener(IOErrorEvent.IO_ERROR,loadShellConfigErrorHandler);
			loader.load(new URLRequest(encodeURI("config/shell.config")));
		}
		
		private function loadShellConfigCompletedHandler(event:Event):void
		{
			var config:ConfigData = new ConfigData(new String(event.target.data));
			this._version = config.getAttribute("version");
			this._date = config.getAttribute("date");
			this._company = config.getAttribute("company");
			this.sceneswfpath = config.getAttribute("sceneswf");
			this.uiswfpath = config.getAttribute("uiswf");
			this.actionconfigpath = config.getAttribute("actionconfigpath");
			
			this.mainserver = config.getAttribute("mainserver");
			this.mainport = int(config.getAttribute("mainport"));
			this.chatserver = config.getAttribute("chatserver");
			this.chatport = int(config.getAttribute("chatport"));
			
			loadSceneSwf();
		}
		
		private function loadShellConfigErrorHandler(event:Event):void
		{
			throw new Error("加载shell.config失败");
		}
		
		private function loadUISwf():void
		{
			if(this.uiswfpath != "none"){
				var loader:Loader = new Loader();
				loader.contentLoaderInfo.addEventListener(Event.COMPLETE,loadUISwfCompletedHandler);
				loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,loadUISwfErrorHandler);
				loader.load(new URLRequest(encodeURI(this.uiswfpath)),new LoaderContext(true,domain));
			}
			else
			{
				loadActionConfig();
			}
		}
		
		private function loadUISwfCompletedHandler(event:Event):void
		{
			_uiApplication = event.target.content;
			loadActionConfig();
		}
		
		private function loadUISwfErrorHandler(event:Event):void
		{
			throw new Error("加载"+this.uiswfpath+"失败");
		}
		
		private function loadSceneSwf():void
		{
			if(this.sceneswfpath != "none"){
				var loader:Loader = new Loader();
				loader.contentLoaderInfo.addEventListener(Event.COMPLETE,loadSceneSwfCompletedHandler);
				loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,loadSceneSwfErrorHandler);
				loader.load(new URLRequest(encodeURI(this.sceneswfpath)),new LoaderContext(true,domain));	
			}
			else
			{
				this.loadUISwf();
			}
		}
		
		private function loadSceneSwfCompletedHandler(event:Event):void
		{
			this._scene = event.target as LoaderInfo;
			this.loadUISwf();
		}
		
		private function loadSceneSwfErrorHandler(event:Event):void
		{
			throw new Error("加载"+this.sceneswfpath+"失败");
		}
		
		private function loadActionConfig():void
		{
			var loader:URLLoader = new URLLoader();
			loader.addEventListener(Event.COMPLETE,loadActionConfigCompletedHandler);
			loader.addEventListener(IOErrorEvent.IO_ERROR,loadActionConfigErrorHandler);
			loader.load(new URLRequest(encodeURI(actionconfigpath)));
		}
		
		private function loadActionConfigCompletedHandler(event:Event):void
		{
			try{
				var config:ConfigData = new ConfigData(event.target.data);
				var types:Array = config.getTypes();
				types.splice(types.indexOf("all"),1);
				this.actionconfig = new Dictionary();
				var defines:Dictionary = new Dictionary;
				var arr:Array = [];
				var roles:Array = [];
				var type:String = null;
				for each(type in types){
					arr = type.split(":");
					if(StringUtil.trim(arr[0]) == "define"){
						defines[StringUtil.trim(arr[1])] = config.getType(type);
					} else {
						roles.push(type);
					}
				}
				var role:String = "";
				var action:String = "";
				var layer:String = "";
				var raconfig:Dictionary;
				var rpcpath:String = "";
				var depths:String = "";
				var depthsarr:Array;
				var dirs:String = "";
				var dirsarr:Array;
				for each(type in roles){
					arr = type.split(":");
					role = arr[0];
					action = arr[1];
					layer = arr[2];
					raconfig = config.getType(type);
					rpcpath = raconfig["rpcpath"];
					depths = raconfig["depths"].indexOf(",")==-1?defines["depths"][raconfig["depths"]]:raconfig["depths"];
					depthsarr = depths.split(",");
					ArrayUtil.changeItemToInt(depthsarr);
					dirs = raconfig["dirs"].indexOf(",")==-1?defines["dirs"][raconfig["dirs"]]:raconfig["dirs"];
					dirsarr = dirs.split(",");
					for(var k:Object in dirsarr){
						dirsarr[k] = ClipDirection.getClipDirectionByString(dirsarr[k]);
					}
					if(!this.actionconfig[StringUtil.trim(role)+":"+StringUtil.trim(action)]){
						this.actionconfig[StringUtil.trim(role)+":"+StringUtil.trim(action)] = new Dictionary();
					}
					this.actionconfig[StringUtil.trim(role)+":"+StringUtil.trim(action)][layer] = [rpcpath,depthsarr,dirsarr];
				}
				this.loadMapsConfig();
			} catch(e:Error){
				throw new Error("actions.config文件配置不对");
			}
			
		}
		
		private function loadActionConfigErrorHandler(event:Event):void
		{
			throw new Error("加载"+this.actionconfigpath+"失败");
		}
		
		private function loadMapsConfig():void
		{
			var loader:URLLoader = new URLLoader();
			loader.dataFormat = URLLoaderDataFormat.BINARY;
			loader.addEventListener(Event.COMPLETE,loadMapsConfigCompletedHandler);
			loader.addEventListener(IOErrorEvent.IO_ERROR,loadMapsConfigErrorHandler);
			loader.load(new URLRequest(encodeURI("config/maps.obj")));
		}
		
		private function loadMapsConfigCompletedHandler(event:Event):void
		{
			var bytes:ByteArray = event.target.data as ByteArray;
			var length:int = bytes.readShort();
			mapsconfig = new Dictionary();
			for(var i:int;i<length;i++){
				bytes.position = 68*i+2;
				var id:int = bytes.readShort();
				var name:String = bytes.readMultiByte(62,"UTF-8");
				var width:int = bytes.readShort();
				var height:int = bytes.readShort();
				this.mapsconfig[id] = {name:name,width:width,height:height};
			}
			this.dispatchEvent(new Event(Event.COMPLETE));
		}
		
		private function loadMapsConfigErrorHandler(event:Event):void
		{
			throw new Error("加载maps.config失败");
		}
	}
}